package dymnd.net;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.LinkedList;

import dymnd.Client;

public class NetworkManager	{
	private Socket connectionSocket = null;
	private ObjectInputStream in;
	private ObjectOutputStream out;
	private Client client;
	boolean stopping = false;
	PacketInThread inThread;
	PacketOutThread outThread;
	public NetworkManager(Client c)	{
		client = c;
		
	}
	
	public synchronized void stop()	{
		stopping = true;
		client.onConnectionLost();
	}
	
	public synchronized void writePacket(Packet p)	{
		outThread.sendPacket(p);
	}
	
	public Packet connect(String host, int port, String username)	{
		try {
			connectionSocket = new Socket(host, port);
			Packet p = new Packet();
			p.username = username;
			in = new ObjectInputStream(connectionSocket.getInputStream());
			Packet inPack = (Packet)in.readObject();
			
			out = new ObjectOutputStream(connectionSocket.getOutputStream());
			out.writeObject(p);
			System.out.println("Starting I/O threads...");
			new Thread(inThread = new PacketInThread()).start();
			new Thread(outThread = new PacketOutThread()).start();
			System.out.println("...Started I/O threads");
			
			return inPack;
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return null;
		}
		
		
		//return null;
	}
	
	private class PacketOutThread implements Runnable	{
		private LinkedList<Packet> packetQueue = new LinkedList<Packet>();
		public void run()	{
			while(!stopping)	{
				//write until the list is at zero
				while(packetQueue.size() != 0){
					try {
						//write each packet out
						out.writeObject(packetQueue.remove(0));
					} catch (IOException e) {
						e.printStackTrace();
						stop();
					}
				}
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
					stop();
					
				}
			}
		}
		
		public synchronized void sendPacket(Packet p)	{
			packetQueue.add(p);
		}
	}
	
	private class PacketInThread	implements Runnable{
		//boolean stopping = false;
		public void run()	{
			while(!stopping)	{
				try {
					client.onPacket((Packet)in.readObject());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					stop();
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					stop();
				}
			}
		}
		
		
		
	}
}